package com.qy.common;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;

public class SolarTerm {
	private static int year;
	private static int month;
	private static int day;
	private static boolean leap;
	static Date baseDate = null;
	static SimpleDateFormat chineseDateFormat = new SimpleDateFormat(
			"yyyy-MM-dd");
	//从1900年开始到2020年的每年的农历立春的日子
	public static List<String> yearlClist = new ArrayList<String>();

	final static long[] STermInfo = new long[] { 0, 21208, 42467, 63836, 85337,
			107014, 128867, 150921, 173149, 195551, 218072, 240693, 263343,
			285989, 308563, 331033, 353350, 375494, 397447, 419210, 440795,
			462224, 483532, 504758 };

	private static final String[] SolarTerm = new String[] { "小寒", "大寒", "立春",
			"雨水", "惊蛰", "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑",
			"立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至" };
	
	//月支
	public static final String[] yz = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
	
	
	static{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Calendar cal = Calendar.getInstance();
		try {
			//阳历
			for (int i = 1900; i < 2020; i++) {
				Calendar callc = sTermDate(i, 2);
				System.out.println(callc.get(Calendar.HOUR)+":"+callc.get(Calendar.MINUTE));
				int y = callc.get(Calendar.YEAR);
				int m = callc.get(Calendar.MONTH) + 1;
				int d = callc.get(Calendar.DAY_OF_MONTH);
				cal.setTime(sdf.parse(y + "-" + m + "-" + d));
				yearlClist.add(getNL(cal));
			}
			System.out.println("###"+StringUtils.join(yearlClist, ","));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] s) throws Exception {
		SolarTerm st = new SolarTerm();

		if (s.length == 3) {
			System.out.println(st.getSoralTerm(Integer.parseInt(s[0]), Integer
					.parseInt(s[1]), Integer.parseInt(s[2])));
		}

		/*System.out.println("##"+st.sTermDate(1995, 2));
		BaZi lunar = new BaZi(st.sTermDate(1995, 2));
		System.out.println("$$"+lunar.toString());
		System.out.println(st.getSoralTerm(2012, 12, 6)+"--------");*/
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		Calendar cal = Calendar.getInstance();
		cal.setTime(sdf.parse("1985-10-08 17:00"));
		System.out.println(st.getNL(cal));
		st.get12Term(2012);
		String i = st.getYZ(cal);
		System.out.println(i);
		//if(i==0){i=}
		//System.out.println(yz[i]);
	}


	public static String getNL(Calendar cal) {
		int monCyl;
		int leapMonth = 0;

		try {
			baseDate = chineseDateFormat.parse("1900-1-31");
		} catch (ParseException e) {
			e.printStackTrace(); //To change body of catch statement use Options | File Templates.

		}

		//求出和1900年1月31日相差的天数 
		int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
		monCyl = 14;

		//用offset减去每农历年的天数 
		// 计算当天是农历第几天 
		//i最终结果是农历的年份 
		//offset是当年的第几天 
		int iYear, daysOfYear = 0;
		for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
			daysOfYear = BaZi.yearDays(iYear);
			offset -= daysOfYear;
			monCyl += 12;
		}
		if (offset < 0) {
			offset += daysOfYear;
			iYear--;
			monCyl -= 12;
		}
		//农历年份 
		year = iYear;

		leapMonth = BaZi.leapMonth(iYear); //闰哪个月,1-12

		leap = false;

		//用当年的天数offset,逐个减去每月（农历）的天数，求出当天是本月的第几天 
		int iMonth, daysOfMonth = 0;
		for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
			//闰月 
			if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
				--iMonth;
				leap = true;
				daysOfMonth = BaZi.leapDays(year);
			} else {
				daysOfMonth = BaZi.monthDays(year, iMonth);
			}
			offset -= daysOfMonth;
			//解除闰月 
			if (leap && iMonth == (leapMonth + 1)) {
				leap = false;
			}
			if (!leap) {
				monCyl++;
			}
		}
		//offset为0时，并且刚才计算的月份是闰月，要校正 
		if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
			if (leap) {
				leap = false;
			} else {
				leap = true;
				--iMonth;
				--monCyl;
			}
		}
		//offset小于0时，也要校正 
		if (offset < 0) {
			offset += daysOfMonth;
			--iMonth;
			--monCyl;
		}
		month = iMonth;
		day = offset + 1;
		return year + "" + ((month>9)?month:("0"+month)) + "" + ((day>9)?day:("0"+day));
	}

	public SolarTerm() {
	}

	/** 核心方法 根据日期得到节气 */
	public String getSoralTerm(Date Date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(Date);

		int y = cal.get(Calendar.YEAR);
		int m = cal.get(Calendar.MONTH) + 1;
		int d = cal.get(Calendar.DAY_OF_MONTH);

		return getSoralTerm(y, m, d);
	}

	/** 核心方法 根据日期(y年m月d日)得到节气 */
	public String getSoralTerm(int y, int m, int d) {
		String solarTerms;
		if (d == sTerm(y, (m - 1) * 2))
			solarTerms = SolarTerm[(m - 1) * 2];
		else if (d == sTerm(y, (m - 1) * 2 + 1))
			solarTerms = SolarTerm[(m - 1) * 2 + 1];
		else {
			// 到这里说明非节气时间
			solarTerms = "";
		}
		return solarTerms;
	}

	// ===== y年的第n个节气为几日(从0小寒起算)
	public static int sTerm(int y, int n) {
		Calendar cal = Calendar.getInstance();
		cal.set(1900, 0, 6, 2, 5, 0);
		long temp = cal.getTime().getTime();
		cal
				.setTime(new Date(
						(long) ((31556925974.7 * (y - 1900) + STermInfo[n] * 60000L) + temp)));
		return cal.get(Calendar.DAY_OF_MONTH);
	}

	public static Calendar sTermDate(int y, int n) {
		Calendar cal = Calendar.getInstance();
		cal.set(1900, 0, 6, 2, 5, 0);
		long temp = cal.getTime().getTime();
		cal
				.setTime(new Date(
						(long) ((31556925974.7 * (y - 1900) + STermInfo[n] * 60000L) + temp)));
		return cal;
	}

	//获取某year的12个节的时间
	public List<Calendar> get12Term(int year){
		//某年的12节 从小寒开始
		List<Calendar> term_current_year = new ArrayList<Calendar>();
		for(int i=0;i<24;i+=2){
			Calendar cal = sTermDate(year,i);
			term_current_year.add(cal);
		}
		return term_current_year;
	}
	
	/**
	 * 传入一个 时间 获取这个时间所在月的月支 年起月的时候用。
	 * @param time
	 * @return
	 */
	public String getYZ(Calendar time){
		int year = time.get(Calendar.YEAR);
		List<Calendar> list = get12Term(year);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		for(Calendar c:list){
			System.out.println("@@"+sdf.format(c.getTime()));
		}
		int i=0;
		while(list.get(i).before(time)){
			i++;
			if(i == 12){
				i = 0;
				break;
			}
		}
		return yz[i];
	}
}